package com.woniuxy.controller;


import com.woniuxy.TransactionPC.RabbitMQProducer;
import com.woniuxy.mapper.ChargingPileMapper;
import com.woniuxy.mapper.ChargingRecordsMapper;
import com.woniuxy.model.dto.*;
import com.woniuxy.model.entity.ChargingPile;
import com.woniuxy.model.entity.ChargingRecords;
import com.woniuxy.model.entity.TransactionOrder;
import com.woniuxy.service.ChargingRecordsService;
import com.woniuxy.service.TransactionOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "客户充电管理")
@Slf4j
@RestController
@RequestMapping("/charging")
public class ChargingController {

    @Autowired
    private ChargingRecordsService chargingRecordsService;

    @Autowired
    private ChargingRecordsMapper chargingRecordsMapper;

    @Autowired
    private ChargingPileMapper chargingPileMapper;

    @Autowired
    private TransactionOrderService transactionOrderService;

    @Autowired
    private RabbitMQProducer rabbitMQProducer;




    @PostMapping("/start")
    public ResponseEntity<?> startCharging(@RequestBody StartChargingDto chargingDto) {
        try {
            // 校验参数完整性
            if (chargingDto.getCustomerId() == null || chargingDto.getPileId() == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("参数缺失");
            }

            // 调用服务处理充电逻辑，生成充电订单号
            String orderNumber = chargingRecordsService.startCharging(chargingDto);

            // 创建交易订单
            TransactionOrder transactionOrder = new TransactionOrder();
            transactionOrder.setCustomerId(chargingDto.getCustomerId());
            transactionOrder.setStationId(chargingDto.getStationId());
            transactionOrder.setPileId(chargingDto.getPileId());
            transactionOrder.setTransactionType("充电支付"); // 交易类型
            transactionOrder.setOrderNo(orderNumber);
            transactionOrder.setTransactionAmount(BigDecimal.ZERO); // 初始金额为 0，结束充电后更新
            transactionOrder.setStatus(0); // 0: 充电中
            transactionOrder.setPaymentStatus(0); // 0: 待付款
            transactionOrder.setCreateTime(new Date());
            transactionOrder.setUpdateTime(new Date());

//            transactionOrderService.createTransactionOrder(transactionOrder);
            // 将订单信息发送到 RabbitMQ 队列
            rabbitMQProducer.sendMessage("transaction_order_queue", transactionOrder);

            // 返回成功信息和订单号
            Map<String, Object> response = new HashMap<>();
            response.put("message", "充电开始成功");
            response.put("order_number", orderNumber);

            return ResponseEntity.ok().body(response);
        } catch (Exception e) {
            log.error("充电启动失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("充电启动失败：" + e.getMessage());
        }
    }





    @GetMapping("/status/{orderNumber}")
    public ResponseEntity<?> getChargingStatus(@PathVariable String orderNumber) {
        try {
            // 1. 查询充电记录
            ChargingRecords record = chargingRecordsMapper.selectByOrderNumber(orderNumber);
            if (record == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("订单不存在");
            }

            // 如果状态为已完成，直接返回当前记录的数据，不再动态计算
            if ("已完成".equals(record.getStatus())) {
                Map<String, Object> result = new HashMap<>();
                result.put("orderNumber", record.getOrderNumber());
                result.put("currentElectricity", record.getElectricityQuantity());
                result.put("currentAmount", record.getAmount());
                result.put("status", record.getStatus());
                return ResponseEntity.ok(result);
            }

            // 2. 查询充电桩功率
            ChargingPile pile = chargingPileMapper.selectById(record.getPileId());
            if (pile == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到对应的充电桩信息");
            }
            BigDecimal pilePower = pile.getPilePower(); // 获取固定功率

            // 3. 获取充电开始时间和当前时间
            Date startTime = record.getCreateTime();
            Date currentTime = new Date();

            // 4. 初始化累计值
            BigDecimal totalElectricity = BigDecimal.ZERO; // 总电量
            BigDecimal totalAmount = BigDecimal.ZERO; // 总费用

            // 5. 按时间段动态计算
            while (startTime.before(currentTime)) {
                // 获取当前时间段收费标准
                String currentTimeStr = new SimpleDateFormat("HH:mm").format(startTime);
                FeeStandardDto feeStandard = chargingRecordsMapper.selectCurrentFeeStandard(record.getStationId(), currentTimeStr);

                if (feeStandard == null) {
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到当前时间段的收费标准");
                }

                // 当前时间段结束时间
                Date periodEnd = getNextPeriodEnd(feeStandard.getStartTime(), feeStandard.getEndTime(), startTime, currentTime);

                // 当前时间段充电时长（小时）
                long periodMillis = Math.min(periodEnd.getTime(), currentTime.getTime()) - startTime.getTime();
                double periodHours = periodMillis / 3600000.0;

                // 计算当前时间段的电量和费用
                BigDecimal electricity = pilePower.multiply(BigDecimal.valueOf(periodHours));
                BigDecimal amount = electricity.multiply(feeStandard.getElectricFee()).add(feeStandard.getServiceFee());

                totalElectricity = totalElectricity.add(electricity);
                totalAmount = totalAmount.add(amount);

                // 更新开始时间为当前时间段结束时间
                startTime = periodEnd;
            }

            // 6. 更新数据库（只更新必要字段）
            chargingRecordsMapper.updateElectricityAndAmountById(record.getId(), totalElectricity, totalAmount);

            // 7. 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("orderNumber", orderNumber);
            result.put("currentElectricity", totalElectricity);
            result.put("currentAmount", totalAmount);
            result.put("status", record.getStatus());
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取实时状态失败：" + e.getMessage());
        }
    }


    private Date getNextPeriodEnd(String startPeriod, String endPeriod, Date startTime, Date currentTime) {
        try {
            // 如果时段是全天，直接返回当天结束时间
            if (startPeriod == null && endPeriod == null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(startTime);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                return calendar.getTime();
            }

            // 如果时段是分时段，解析结束时间
            SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
            Date endTime = timeFormat.parse(endPeriod);

            // 将结束时间设定为当天的时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);
            calendar.set(Calendar.HOUR_OF_DAY, endTime.getHours());
            calendar.set(Calendar.MINUTE, endTime.getMinutes());
            calendar.set(Calendar.SECOND, 0);
            Date periodEnd = calendar.getTime();

            // 如果结束时间超过当前时间，则返回当前时间
            return periodEnd.before(currentTime) ? periodEnd : currentTime;
        } catch (Exception e) {
            throw new RuntimeException("无法确定时段结束时间", e);
        }
    }




    @PostMapping("/stop/{orderNumber}")
    public ResponseEntity<?> stopCharging(@PathVariable String orderNumber) {
        try {
            // 查询充电记录
            ChargingRecords record = chargingRecordsMapper.selectByOrderNumber(orderNumber);
            if (record == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("订单不存在");
            }

            // 如果状态为已完成，则直接返回当前结果
            if ("已完成".equals(record.getStatus())) {
                Map<String, Object> result = new HashMap<>();
                result.put("orderNumber", record.getOrderNumber());
                result.put("totalElectricity", record.getElectricityQuantity());
                result.put("totalAmount", record.getAmount());
                result.put("status", record.getStatus());
                return ResponseEntity.ok(result);
            }

            // 查询充电桩功率
            ChargingPile pile = chargingPileMapper.selectById(record.getPileId());
            if (pile == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到对应的充电桩信息");
            }
            BigDecimal pilePower = pile.getPilePower(); // 获取固定功率

            // 计算总电量和总费用
            Date startTime = record.getCreateTime();
            Date currentTime = new Date();
            BigDecimal totalElectricity = BigDecimal.ZERO; // 总电量
            BigDecimal totalAmount = BigDecimal.ZERO; // 总费用

            while (startTime.before(currentTime)) {
                String currentTimeStr = new SimpleDateFormat("HH:mm").format(startTime);
                FeeStandardDto feeStandard = chargingRecordsMapper.selectCurrentFeeStandard(record.getStationId(), currentTimeStr);

                if (feeStandard == null) {
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到当前时间段的收费标准");
                }

                Date periodEnd = getNextPeriodEnd(feeStandard.getStartTime(), feeStandard.getEndTime(), startTime, currentTime);
                long periodMillis = Math.min(periodEnd.getTime(), currentTime.getTime()) - startTime.getTime();
                double periodHours = periodMillis / 3600000.0;

                BigDecimal electricity = pilePower.multiply(BigDecimal.valueOf(periodHours));
                BigDecimal amount = electricity.multiply(feeStandard.getElectricFee()).add(feeStandard.getServiceFee());

                totalElectricity = totalElectricity.add(electricity);
                totalAmount = totalAmount.add(amount);

                startTime = periodEnd;
            }

            // 更新充电记录状态
            record.setElectricityQuantity(totalElectricity);
            record.setAmount(totalAmount);
            record.setStatus("已完成");
            record.setUpdateTime(currentTime);
            chargingRecordsMapper.updateById(record);

            // 更新交易订单状态和金额
            TransactionOrder transactionOrder = transactionOrderService.getOrderByOrderNo(orderNumber);
            if (transactionOrder != null) {
                transactionOrder.setTransactionAmount(totalAmount); // 更新交易金额
                transactionOrder.setStatus(1); // 设置状态为已完成
                transactionOrder.setPaymentStatus(0); // 保持为待付款状态
                transactionOrder.setUpdateTime(currentTime); // 更新修改时间
                transactionOrderService.updateOrder(transactionOrder);
            }

            // 更新充电桩状态为“空闲中”
            pile.setPileStatus("空闲中");
            chargingPileMapper.updateById(pile);



            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("orderNumber", orderNumber);
            result.put("totalElectricity", totalElectricity);
            result.put("totalAmount", totalAmount);
            result.put("status", record.getStatus());
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("停止充电失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("停止充电失败：" + e.getMessage());
        }
    }



    @GetMapping("/details/{orderNumber}")
    public ResponseEntity<?> getChargingDetails(@PathVariable String orderNumber) {
        try {

            // 1. 查询充电记录
            ChargingRecords record = chargingRecordsMapper.selectByOrderNumber(orderNumber);
            if (record == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("订单不存在");
            }
            getChargingStatus(orderNumber);

            // 2. 查询充电桩信息
            ChargingPile pile = chargingPileMapper.selectById(record.getPileId());
            if (pile == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到对应的充电桩信息");
            }

            // 3. 计算剩余时间和充电百分比
            BigDecimal batteryCapacity = BigDecimal.valueOf(100); // 电池容量固定为 100kWh
            BigDecimal currentElectricity = record.getElectricityQuantity();
            BigDecimal remainingElectricity = batteryCapacity.subtract(currentElectricity);

            // 计算剩余时间 = 剩余电量 / 桩功率
            BigDecimal remainingTime = remainingElectricity.divide(pile.getPilePower(), 2, RoundingMode.HALF_UP); // 单位：小时

            // 计算充电百分比
            BigDecimal percentage = currentElectricity.divide(batteryCapacity, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));

            // 4. 组织返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("orderNumber", record.getOrderNumber());
            result.put("pileCode", pile.getPileCode());
            result.put("pilePower", pile.getPilePower());
            result.put("electricityQuantity", currentElectricity);
            result.put("amount", record.getAmount());
            result.put("createTime", record.getCreateTime());
            result.put("remainingTime", remainingTime); // 剩余时间（小时）
            result.put("percentage", percentage); // 当前充电百分比
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("获取充电详情失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取充电详情失败：" + e.getMessage());
        }
    }

    @GetMapping("/pile/{pileId}")
    public ResponseEntity<?> getPileDetails(@PathVariable Long pileId) {
        try {
            ChargingPile pile = chargingPileMapper.selectById(pileId);
            if (pile == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("未找到对应的充电桩信息");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("pileCode", pile.getPileCode()); // 终端编号
            result.put("pilePower", pile.getPilePower()); // 充电功率
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取充电桩详情失败：" + e.getMessage());
        }
    }

    @PostMapping("/refund")
    public ResponseEntity<?> applyRefund(@RequestBody Map<String, Object> request) {
        try {
            // 从请求体中获取参数
            String orderNumber = (String) request.get("orderNumber");
            BigDecimal refundAmount = new BigDecimal(String.valueOf(request.get("refundAmount")));
            String refundDescription = (String) request.get("refundDescription");

            // 调用服务层处理退款
            boolean success = chargingRecordsService.applyRefund(orderNumber, refundAmount, refundDescription);
            if (success) {
                return ResponseEntity.ok(Collections.singletonMap("success", true));
            } else {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Collections.singletonMap("success", false));
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Collections.singletonMap("success", false));
        }
    }

    @ApiOperation("查询退款订单")
    @GetMapping("/refunds")
    public ResponseEntity<?> getRefundOrders(@RequestParam("customerId") Long customerId) {
        try {
            List<ChargingRecords> refunds = chargingRecordsMapper.getRefundOrdersByCustomerId(customerId);
            return ResponseEntity.ok(refunds);
        } catch (Exception e) {
            log.error("获取退款订单失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("获取退款订单失败");
        }
    }

    @ApiOperation("管理员处理退款")
    @PostMapping("/processRefund")
    public ResponseEntity<?> processRefund(@RequestBody ProcessRefundDto processRefundDto) {
        try {
            ChargingRecords record = chargingRecordsMapper.selectByOrderNumber(processRefundDto.getOrderNumber());
            if (record == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("订单不存在");
            }

            // 更新退款状态和描述
            record.setRefundStatus(processRefundDto.getRefundStatus());
            record.setProcessDescription(processRefundDto.getProcessDescription());
            if (processRefundDto.getRefundStatus() == 2) { // 如果同意退款
                record.setRefundAmount(processRefundDto.getRefundAmount());
                record.setRefundTime(new Date());
            }
            chargingRecordsMapper.updateById(record);

            return ResponseEntity.ok("退款处理成功");
        } catch (Exception e) {
            log.error("处理退款失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("处理退款失败");
        }
    }









}
